package com.ccx.demo.business.code.service;

import com.ccx.demo.business.code.dao.jpa.CodeSearchIdRepository;
import com.ccx.demo.business.code.entity.TabCodeSearchId;
import com.google.common.base.Strings;
import com.querydsl.core.QueryResults;
import com.support.mvc.entity.base.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.*;

//import static com.ccx.demo.config.init.AppInit.getCacheManager; // 若使用缓存需要解开代码

/**
 * 服务接口实现类：测试 SearchId 模板表
 *
 * @author 谢长春 on 2022-02-16 V20220301
 */
@Slf4j
@Service
@Validated
@RequiredArgsConstructor
@Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
public class CodeSearchIdService
//      , ITabCodeSearchIdCache
{
    private final CodeSearchIdRepository repository;
//     /** // 若使用缓存需要解开代码
//      * 获取当前缓存管理器，用于代码控制缓存
//      *
//      * @return {@link Cache}
//      */
//     public Cache getCache() {
//         return Objects.requireNonNull(getCacheManager().getCache(CACHE_ROW_BY_ID), "未获取到缓存管理对象:".concat(CACHE_ROW_BY_ID));
//     }
//
//     /** // 若使用缓存需要解开代码
//      * 清除多个 key 对应的缓存
//      *
//      * @param ids {@link TabCodeSearchId#getId()}
//      */
//     public void clearKeys(final Collection<String> ids) {
//         ids.stream().distinct().forEach(id -> getCache().evict(id));
//     }

    /**
     * 测试 SearchId 模板表 按ID查询对象，注意这里可能有 deleted 为 YES 的数据
     *
     * @param id {@link String} 数据ID
     * @return {@link Optional<TabCodeSearchId>} 实体对象
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public Optional<TabCodeSearchId> findById(final String id) {
        if (Strings.isNullOrEmpty(id)) {
            return Optional.empty();
        }
        return repository.findById(id)
                .map(TabCodeSearchId::cloneObject); // 必须要 clone ，如果直接对持久化对象调用 set 方法，会触发更新动作
//         return Optional.ofNullable(repository.findCacheById(id)).map(TabCodeSearchId::cloneObject); // 若使用缓存需要解开代码
    }

    /**
     * 测试 SearchId 模板表 按条件分页查询列表
     *
     * @param condition {@link TabCodeSearchId} 查询条件
     * @param page      {@link Page} 分页排序集合
     * @return {@link QueryResults<TabCodeSearchId>} 分页对象
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public @NotNull(message = "返回值不能为null") QueryResults<TabCodeSearchId> page(
            @NotNull(message = "【condition】不能为null") final TabCodeSearchId condition,
            @NotNull(message = "【page】不能为null") @Valid final Page page) {
        return repository.page(condition, page);
    }

//// 非必要情况下不要开放列表查询方法，因为没有分页控制，容易内存溢出。大批量查询数据应该使用分页查询
//    /**
//     * 测试 SearchId 模板表 按条件查询列表
//     *
//     * @param condition {@link TabCodeSearchId} 查询条件
//     * @return {@link List<TabCodeSearchId>} 结果集合
//     */
//    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
//    public @NotNull(message = "返回值不能为null") List<TabCodeSearchId> list(
//            @NotNull(message = "【condition】不能为null") final TabCodeSearchId condition) {
//        return repository.list(condition);
//    }
//

    /**
     * 测试 SearchId 模板表 按 id 批量查询列表，注意这里可能有 deleted 为 true 的数据
     *
     * @param ids {@link String}  数据 id 集合
     * @return {@link List<TabCodeSearchId>} 结果集合
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public @NotNull(message = "返回值不能为null") List<TabCodeSearchId> listByIds(final Collection<String> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return Collections.emptyList();
        }
        return repository.listByIds(ids);
    }

    /**
     * 测试 SearchId 模板表 按 id 批量查询列表，返回 map ， key 为数据 id ， 注意这里可能有 deleted 为 true 的数据
     *
     * @param ids {@link String} 数据 id 集合
     * @return {@link List<TabCodeSearchId>} 结果集合
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public @NotNull(message = "返回值不能为null") Map<String, TabCodeSearchId> mapByIds(final Set<String> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return Collections.emptyMap();
        }
        return repository.mapByIds(ids);
    }

}
